Skip to content

docs: HTTP gateway extensions how-to and zstd config flags#85

Merged
ankurs merged 8 commits intomainfrom
docs/gateway-extensions
May 2, 2026
Merged

docs: HTTP gateway extensions how-to and zstd config flags#85
ankurs merged 8 commits intomainfrom
docs/gateway-extensions

Conversation

@ankurs
Copy link
Copy Markdown
Member

@ankurs ankurs commented May 1, 2026

Summary

  • New howto/gateway-extensions.md covering core's RegisterServeMuxOption and RegisterHTTPMarshaler hooks. Includes an ordering-rules table (last-write-wins vs additive options) and four worked recipes: MessagePack marshaler via shamaton/msgpack + protojson bridge, default JSONPb tuning via runtime.MIMEWildcard, request-size middleware via WithMiddlewares, and a vendor error envelope via WithErrorHandler.
  • howto/index.md — new row linking to the page.
  • config-reference.mdDISABLE_ZSTD_COMPRESSION and PREFER_ZSTD rows documenting the new core flags.
  • tests/navigation.spec.ts/howto/gateway-extensions/ added to the Playwright howtoPages list so CI asserts the page loads.

Depends on

go-coldbrew/core#88. The page references core.RegisterHTTPMarshaler / core.RegisterServeMuxOption, which land in that PR. Safe to merge after core PR 88 is released; merging earlier just means the snippets reference an unreleased API for a window.

Test plan

  • Page front matter follows the existing convention (layout, title, parent, nav_order, description 120–160 chars).
  • npx playwright test --list parses the updated spec and includes the new /howto/gateway-extensions/ test case.
  • Live Playwright nav run — local Ruby/Jekyll env can't build the site here; CI will run the live assertions on this branch.

Out of scope

  • Bumping the cb-main submodule pointer — handled in a follow-up chore: sync submodules after both this PR and the core release land.

Summary by CodeRabbit

  • New Features

    • HTTP gateway adds configurable zstd compression options (DISABLE_ZSTD default false, PREFER_ZSTD default true), including behavior when overall HTTP compression is disabled and how PREFER_ZSTD influences Accept-Encoding negotiation.
    • Support for plugging in custom HTTP marshalers and gateway-wide middleware for request handling and response formatting (registration must occur before server start).
  • Documentation

    • New how-to guide with recipes for custom marshalers, middleware, request-size limits, and error handling; added to the How-To index.
  • Tests

    • UI and content tests expanded to cover the new how-to page and its links.

Add a new how-to page covering core's RegisterServeMuxOption and
RegisterHTTPMarshaler hooks. Page contents:

- Overview of the two functions and the init-only constraint.
- Ordering rules table (last-write-wins vs additive options) with the
  WithIncomingHeaderMatcher caveat.
- Worked recipes:
  - MessagePack marshaler via shamaton/msgpack with a protojson bridge
    for proto WKT correctness.
  - Tuning the default runtime.JSONPb (EmitUnpopulated, UseProtoNames,
    Indent) by registering for runtime.MIMEWildcard.
  - Per-route middleware via runtime.WithMiddlewares (request size limit
    example).
  - Custom error handler via runtime.WithErrorHandler returning a
    vendor-specific error envelope.
- "When to reach for these hooks" guidance pointing back at
  Interceptors for gRPC-side concerns.

Also:
- howto/index.md — new index row linking to the page.
- config-reference.md — DISABLE_ZSTD_COMPRESSION and PREFER_ZSTD rows
  documenting the new core flags.
- tests/navigation.spec.ts — add /howto/gateway-extensions/ to the
  Playwright howtoPages list so CI asserts the page loads.
Copilot AI review requested due to automatic review settings May 1, 2026 17:33
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2b33642c-cdaf-4b32-9dbd-621becfce0b4

📥 Commits

Reviewing files that changed from the base of the PR and between f5944a1 and 6f64623.

📒 Files selected for processing (3)
  • howto/gateway-extensions.md
  • tests/content.spec.ts
  • tests/links.spec.ts
✅ Files skipped from review due to trivial changes (1)
  • howto/gateway-extensions.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/links.spec.ts
  • tests/content.spec.ts

📝 Walkthrough

Walkthrough

Adds a new "HTTP Gateway Extensions" how-to documenting init-time grpc-gateway hooks and example recipes, adds two zstd-related HTTP gateway config flags to the configuration reference, updates the how-to index, and extends site tests to include the new page.

Changes

HTTP Gateway Extensions + Config & Tests

Layer / File(s) Summary
API Surface / Signatures
github.com/go-coldbrew/core
Adds init-only registration functions RegisterServeMuxOption(opt runtime.ServeMuxOption) and RegisterHTTPMarshaler(mime string, m runtime.Marshaler).
How-To Doc Front Matter & Overview
howto/gateway-extensions.md
New document with Jekyll front matter, purpose, and init-time registration requirement plus concurrency note.
Behavior / Ordering Rules
howto/gateway-extensions.md
Documents ordering vs ColdBrew built-ins, last-write-wins for marshaler overrides, additive stacking for some options, middleware stacking point, and warning about overriding WithIncomingHeaderMatcher affecting HTTP_HEADER_PREFIXES.
Recipes / Examples
howto/gateway-extensions.md
Provides copy-pastable recipes: MessagePack marshaler (proto↔msgpack bridge with NewDecoder/NewEncoder), tuning runtime.JSONPb for wildcard JSON, gateway-wide middleware using http.MaxBytesReader, and custom runtime.WithErrorHandler example.
Configuration Reference
config-reference.md
Adds DISABLE_ZSTD_COMPRESSION (default false) and PREFER_ZSTD (default true) to HTTP gateway config table; notes both ignored when DISABLE_HTTP_COMPRESSION=true and explains PREFER_ZSTD's impact on Accept-Encoding negotiation vs gzip.
Site Index & Navigation
howto/index.md
Adds “Add custom HTTP marshalers or middleware” linking to /howto/gateway-extensions/.
Tests — Page Loading / Navigation
tests/navigation.spec.ts
Adds /howto/local-dev/ and /howto/gateway-extensions/ to howtoPages so page-loading test visits the new guide(s).
Tests — SEO / TOC
tests/content.spec.ts
Adds /howto/gateway-extensions/ to pagesWithDescriptions and to howtoPages so meta-description and TOC assertions run for the new page.
Tests — Internal Links Crawl
tests/links.spec.ts
Adds /howto/gateway-extensions/ to pagesToCrawl and asserts anchor #recipe-gateway-middleware exists on that page.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I nibble docs and hooks so fine,
I stitch marshalers with a hop and line,
Zstd flags tucked gently in the config bed,
Middleware and handlers lightly led,
Hop on—ColdBrew’s gateways bloom ahead!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the two main changes: documentation for HTTP gateway extensions (new how-to page with registration hooks and recipes) and zstd compression configuration flags (new config variables).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/gateway-extensions

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 60 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds new documentation and navigation coverage for extending ColdBrew’s grpc-gateway HTTP layer, and documents new HTTP compression-related config flags.

Changes:

  • New How-To page documenting RegisterServeMuxOption / RegisterHTTPMarshaler hooks with ordering rules and recipes.
  • Adds the new How-To link to the How-To index and ensures Playwright CI checks the page loads.
  • Documents DISABLE_ZSTD_COMPRESSION and PREFER_ZSTD in the configuration reference.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
tests/navigation.spec.ts Adds the new How-To URL to the Playwright “howto page loads” list.
howto/index.md Adds a row linking to the new “HTTP Gateway Extensions” page.
howto/gateway-extensions.md Introduces a new How-To page describing HTTP gateway extension hooks and recipes.
config-reference.md Documents two new HTTP gateway compression flags (zstd-specific controls).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread howto/gateway-extensions.md Outdated
Addresses Copilot review feedback on PR #85. Match the established
quickstart pattern (cb := core.New(cfg) followed by cb.Run()) instead
of pointing readers at a non-existent core.Run() free function.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread howto/gateway-extensions.md Outdated
Comment thread howto/gateway-extensions.md
Comment thread howto/gateway-extensions.md Outdated
Comment thread howto/gateway-extensions.md Outdated
- Replace 'a package init' with 'a package-level init() function' since
  package init isn't a Go construct.
- Add a warning callout that the msgpack NewDecoder reads the full
  request body via io.ReadAll; pair with http.MaxBytesReader middleware
  (which the per-route middleware recipe already demonstrates).
- Drop the 'coldbrew' import alias and use 'core' consistently across
  all four PreStart snippets, matching the convention in quickstart.md
  and other how-to pages.
- Remove the unused [ColdBrew cookiecutter] reference link.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@howto/gateway-extensions.md`:
- Around line 138-147: The import blocks in the PreStart examples are missing
the context package needed for the PreStart function signature; update the
import lists that accompany the PreStart snippets to include "context" so that
functions referencing context.Context (e.g., the PreStart method on Service)
compile—specifically add "context" to the import block shown above the PreStart
function and to the other identical snippets that reference context.Context.
- Around line 225-236: envelopeErrorHandler currently ignores the error returned
by m.Marshal which can produce an empty/invalid response; update the function
(envelopeErrorHandler) to check the error from m.Marshal(payload) and handle it:
if marshal succeeds, write the body as before; if marshal fails, log the marshal
error and write a safe fallback response (e.g., a minimal JSON/error string or
use http.Error) and ensure the HTTP status
(runtime.HTTPStatusFromCode(s.Code())) and Content-Type are still set
appropriately; reference m.Marshal, payload, w.Write, and
runtime.HTTPStatusFromCode when making the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4cd815b2-6767-4ce8-a582-4ee632cd8ef1

📥 Commits

Reviewing files that changed from the base of the PR and between 0b39a6d and e8cce3a.

📒 Files selected for processing (4)
  • config-reference.md
  • howto/gateway-extensions.md
  • howto/index.md
  • tests/navigation.spec.ts

Comment thread howto/gateway-extensions.md
Comment thread howto/gateway-extensions.md
- Add missing 'context' import to the msgpack, JSONPb, and middleware
  PreStart snippets so they compile as pasted.
- Restructure envelopeErrorHandler to marshal the payload first and
  fall back via http.Error on marshal failure, before writing
  Content-Type or the status code. The previous version discarded
  the marshal error and could leave the client with status set but
  an empty body.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread howto/gateway-extensions.md
Comment thread howto/gateway-extensions.md Outdated
Comment thread howto/gateway-extensions.md Outdated
- Rename 'Recipe: Per-route middleware' to 'Recipe: Gateway middleware'.
  runtime.WithMiddlewares is mux-wide, not route-scoped; the old heading
  contradicted the body. Update the cross-reference link from the
  msgpack callout to match.
- Rewrite the JSONPb intro to clarify that the wildcard registration
  only overrides the *fallback* marshaler. Add a note that callers who
  bind application/json explicitly (e.g. USE_JSON_BUILTIN_MARSHALLER=true)
  need to register the tuned JSONPb for that concrete MIME too.
- Add a warning callout under the error-handler recipe noting that the
  map[string]any envelope only works for JSON-shaped marshalers.
  Proto-only marshalers (application/proto, application/protobuf) need
  a proto.Message such as status.Convert(err).Proto() or a custom
  generated proto envelope.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread config-reference.md
Comment thread tests/navigation.spec.ts
Comment thread howto/index.md Outdated
Comment thread howto/gateway-extensions.md
- Move the gateway-extensions row to the bottom of the howto index
  table to match its nav_order (20), keeping the index in sync with
  the sidebar order.
- Add /howto/local-dev/ to the Playwright howtoPages list. It's been
  linked from howto/index.md but missing from the smoke suite.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread howto/gateway-extensions.md Outdated
func RegisterHTTPMarshaler(mime string, m runtime.Marshaler)
```

Use them to add custom marshalers (MessagePack, CBOR, vendor-specific JSON), tune the default protojson marshaler, register per-route middleware, install a custom error handler, or wire forward-response hooks — anything `runtime.ServeMuxOption` lets you do.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in f5944a1 — Overview now reads "register gateway middleware" to match the recipe heading and the body's mux-wide framing.

Comment thread howto/gateway-extensions.md Outdated
```

{: .warning }
This snippet marshals a `map[string]any` envelope. JSON-shaped marshalers (`runtime.JSONPb`, `runtime.JSONBuiltin`, the JSON-bridged msgpack recipe above) accept it, but proto-only marshalers (`application/proto`, `application/protobuf`) require a `proto.Message` and would hit the `http.Error` fallback path. For a portable envelope, marshal `status.Convert(err).Proto()` (a `*google.golang.org/genproto/googleapis/rpc/status.Status` that implements `proto.Message`) instead of a freeform map — or define your own envelope as a generated proto.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caught in f5944a1. The callout now only lists runtime.JSONPb and runtime.JSONBuiltin as accepting arbitrary Go values; the MessagePack recipe and runtime.ProtoMarshaller are explicitly grouped with the marshalers that would reject map[string]any and fall through to http.Error.

Comment thread tests/navigation.spec.ts
Comment on lines +33 to +34
"/howto/local-dev/",
"/howto/gateway-extensions/",
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in f5944a1 — added /howto/gateway-extensions/ to the SEO meta-description list and the TOC howtoPages list in content.spec.ts, and added it (plus /howto/) to the link-crawl pagesToCrawl in links.spec.ts so broken links and missing meta/TOC on the new page now fail CI.

Comment thread howto/index.md
| Manage readiness with workers | [Readiness Patterns](/howto/readiness) |
| Set up local dev with Docker | [Local Development](/howto/local-dev) |
| Add JWT / API key auth | [Authentication](/howto/auth) |
| Add custom HTTP marshalers or middleware | [HTTP Gateway Extensions](/howto/gateway-extensions) |
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in f5944a1/howto/ is now in pagesToCrawl, so a typo in this row's href would surface as a broken link in CI.

- gateway-extensions.md: fix 'register per-route middleware' wording in
  the Overview to 'register gateway middleware', matching the recipe
  heading downstream.
- gateway-extensions.md: rewrite the error-envelope warning callout.
  Only runtime.JSONPb and runtime.JSONBuiltin accept arbitrary Go
  values; the MessagePack recipe earlier on the page type-asserts
  proto.Message and would also reject map[string]any, so listing it
  alongside the JSON marshalers was wrong.
- tests/links.spec.ts: add /howto/ and /howto/gateway-extensions/ to
  pagesToCrawl so a typo in the index entry or the new page's outgoing
  links is caught by the link-crawl suite.
- tests/content.spec.ts: add /howto/gateway-extensions/ to the meta-
  description SEO list and the howtoPages list for the TOC test.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@howto/gateway-extensions.md`:
- Around line 58-112: The MessagePack marshaler (Marshaler.Marshal and
Marshaler.Unmarshal used with ContentType "application/msgpack") converts
protojson into a generic any via encoding/json which decodes numbers to float64
and can lose precision for large int64/uint64; add a visible warning callout
immediately after the curl/Content-Type paragraph (and the corresponding
secondary location mentioned in the review) explaining that decoding into
any/interface{} with encoding/json may convert integers to float64 and thus lose
precision for values > 2^53-1, and advise readers to avoid relying on this
bridge for large integer fields or to use a custom encoder/alternative approach.
- Around line 262-265: Reword the consecutive bullets under the "When to reach
for these hooks" list to avoid repeating "You need ..." by editing one of the
items (for example, change "You want the defaults of `runtime.JSONPb`
adjusted..." to "Adjust the defaults of `runtime.JSONPb` (field naming,
empty-value emission, indentation)" or similar); update any adjacent bullet that
starts with "You need ..." so the list reads more varied while preserving the
original meaning and examples (`msgpack, CBOR, YAML, vendor-specific binary`,
`raw-body access, file uploads, response streaming wrappers, request size
limits`, and the `runtime.JSONPb`/error envelope mentions).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e20c1e78-255e-4cd5-8c6e-38f3a357a42e

📥 Commits

Reviewing files that changed from the base of the PR and between 77357ae and f5944a1.

📒 Files selected for processing (3)
  • howto/gateway-extensions.md
  • tests/content.spec.ts
  • tests/links.spec.ts
✅ Files skipped from review due to trivial changes (2)
  • tests/links.spec.ts
  • tests/content.spec.ts

Comment thread howto/gateway-extensions.md
Comment thread howto/gateway-extensions.md Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread howto/gateway-extensions.md Outdated
Comment thread howto/gateway-extensions.md Outdated
Comment thread tests/links.spec.ts
Comment thread tests/content.spec.ts
Comment thread tests/content.spec.ts
- gateway-extensions.md: add a precision-loss warning to the
  MessagePack recipe. The protojson-encoding/json-msgpack bridge
  decodes JSON numbers into 'any' as float64; int64/uint64 values
  greater than 2^53-1 lose precision through the round-trip. Point
  callers at a protoreflect-direct encoder for those fields.
- gateway-extensions.md: tighten the JSONPb intro to acknowledge that
  runtime.MIMEWildcard serves both inbound (Content-Type) and
  outbound (Accept) sides, and update the follow-up note to mirror
  that on the override case.
- gateway-extensions.md: rephrase the 'When to reach for these hooks'
  bullets so we don't have three consecutive 'You need …' bullets,
  and broaden the interceptors mental-model line to cover both
  server- and client-side interceptors (retries are a client concern).
- tests/links.spec.ts: extend pagesWithAnchors with the
  #recipe-gateway-middleware fragment so the new in-page anchor
  link is verified.
- tests/content.spec.ts: add /howto/local-dev/ to both
  pagesWithDescriptions (SEO) and the TOC howtoPages list. The page
  was already linked from howto/index.md and the navigation smoke
  list but was missing from the SEO and TOC suites.
@ankurs ankurs merged commit 6a45e5f into main May 2, 2026
7 checks passed
@ankurs ankurs deleted the docs/gateway-extensions branch May 2, 2026 11:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants